Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: differentiate scalar parsing from byte arrays #194

Merged
merged 1 commit into from
Sep 28, 2023

Conversation

AaronFeickert
Copy link
Contributor

@AaronFeickert AaronFeickert commented Aug 9, 2023

Currently, creating a scalar RistrettoSecretKey from a byte array performs modular reduction on 32 bytes. For cases where the input is intended to be canonical, this is suboptimal. For cases where the input is produced from a hashing operation, wide reduction should be used to mitigate bias.

This work renames SecretKey::from_bytes to SecretKey::from_canonical_bytes to support an underlying ByteArray trait update. In the case of RistrettoSecretKey, it uses the curve library's canonical parser and returns an error if the provided byte slice is not a canonical scalar encoding.

It also adds a new SecretKey::from_uniform_bytes function that uses wide reduction. For constructions like signatures and KDFs that use hashing operations to produce scalar values, this function is used and the underlying hashers are updated to produce 64-byte output in the case of RistrettoSecretKey.

It updates the Schnorr signature API to support raw signing and verification using challenge byte slices that are either canonical encodings or uniform. It renames several existing functions for clarity.

It corrects a few typos that were discovered along the way.

Closes #189.

BREAKING CHANGE: This changes the way that scalars are produced from byte arrays, modifies the SecretKey trait and corresponding RistrettoSecretKey implementation, and updates the Schnorr signature API.

Copy link
Contributor

@CjS77 CjS77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits re: one of the comments. Otherwise LGTM

src/ristretto/ristretto_keys.rs Outdated Show resolved Hide resolved
src/ristretto/ristretto_keys.rs Outdated Show resolved Hide resolved
@CjS77
Copy link
Contributor

CjS77 commented Aug 9, 2023

ACK

@CjS77 CjS77 added the P-merge The PR can me merged. label Aug 9, 2023
@AaronFeickert AaronFeickert requested a review from CjS77 August 9, 2023 23:33
@AaronFeickert AaronFeickert force-pushed the scalar-byte-array branch 2 times, most recently from ddc40c7 to bec8195 Compare August 10, 2023 17:34
Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, just some comments:

  • Why force from_bytes to use the underlying from_canonical_bytes call? Why not add an additional method from_canonical_bytes method to use the underlying from_canonical_bytes call? This way the change will be non-breaking.
  • If the intention is to prohibit the underlying from_bytes_mod_order call, I would propose changing the name of from_bytes to from_canonical_bytes.

src/hashing.rs Outdated Show resolved Hide resolved
@AaronFeickert
Copy link
Contributor Author

@hansieodendaal thanks for the review.

  • Why force from_bytes to use the underlying from_canonical_bytes call? Why not add an additional method from_canonical_bytes method to use the underlying from_canonical_bytes call? This way the change will be non-breaking.

There's no good reason to have scalar parsing use the underlying Scalar::from_bytes_mod_order call. I'd much rather have it be breaking and use a consistent approach.

  • If the intention is to prohibit the underlying from_bytes_mod_order call, I would propose changing the name of from_bytes to from_canonical_bytes.

Unfortunately implementing ByteArray requires this.

Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

src/ristretto/ristretto_keys.rs Outdated Show resolved Hide resolved
@AaronFeickert
Copy link
Contributor Author

AaronFeickert commented Aug 27, 2023

After discussion, it sounds like the preferred approach is to rename the ByteArray function from_bytes to from_canonical_bytes and to have SecretKey use from_bytes_wide. This will reduce confusion and force all existing from_bytes uses to pick one or the other.

@AaronFeickert AaronFeickert marked this pull request as ready for review September 25, 2023 21:40
Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, sensible and easy to reason about.

ACK

Cargo.toml Outdated Show resolved Hide resolved
Copy link
Contributor

@SWvheerden SWvheerden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@stringhandler stringhandler merged commit f9b6cb8 into tari-project:main Sep 28, 2023
4 checks passed
@AaronFeickert AaronFeickert deleted the scalar-byte-array branch September 28, 2023 14:19
SWvheerden added a commit to tari-project/tari that referenced this pull request Nov 2, 2023
Description
---
Updates key parsing to differentiate between canonical- and
reduction-based use cases. Makes several updates to account for
`EpochTime` changes. Updates genesis data.

Motivation and Context
---
An [update](tari-project/tari-crypto#194) to
`tari-crypto` differentiates secret key parsing between cases that
should use canonical byte arrays, and those that use random byte arrays
requiring modular wide reduction.

This PR makes corresponding changes to account for this.

It also makes several updates required since the `tari_utilities`
release used here also makes breaking `EpochTime` changes that can't be
cleanly done separately.

How Has This Been Tested?
---
Existing tests pass. Uses of parsed secret keys have been manually
inspected for correctness.

What process can a PR reviewer use to test or verify this change?
---
Assert that secret keys and scalars instantiated from byte arrays use
the appropriate approach: parsing from canonical byte arrays, or modular
wide reduction from uniform byte arrays.

Confirm that `EpochTime` changes reflect the intended logic, especially
relating to timestamp and difficulty handling.

BREAKING CHANGE: This modifies how secret keys and scalars are
constructed and is therefore a breaking change.

---------

Co-authored-by: Aaron Feickert <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-merge The PR can me merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Differentiate scalar creation by canonical and reduction cases
6 participants